/*
下面是程序处理步骤：
A.  新增是主要更新LastVisitDate__c，LastVisitDate_schedule__c
    1.  先把数据分这个月和上个月份放在两个list里面，比如当前月的列表和上个月的列表
    2.  然后处理这个月LastVisitDate__c数据，如果有相同店面只取日期最大的店面，帅选完之后更新当前记录的LastVisitDate__c为starttime的日期
    3.  根据当前数据的店面id，把其他的店面这月或上个月有拜访日期或者有分销日期的记录都查询出来。
    4.  根据步骤2的店面去匹配3中数据，如果店面名称相同则更新其LastVisitDate__c为空
    5.  接着处理LastVisitDate_schedule__c，先把计划内的数据放到list里面，然后也是相同店面只取日期最大的店面，帅选完之后更新当前记录的LastVisitDate_schedule__c。
    6.  用5步骤得到的数据去匹配3中的数据，如果店面名称相同则更新其LastVisitDate_schedule__c。
    7.  上个月的列表如果有数据，处理步骤跟当月一样，只是时间要判端是否为上个月。

B.  修改分销时更新LastDistributionDate__c
    1.  然后判断当前记录是有分销数据修改才继续下面的步骤。
    //2.  把分销大于0的记录分别放在这个月和上个月list里面
    3.  对于分销等于0，而且是它们原来的分销是大于0的记录分别放在这个月和上个月list里面
    //4.  接着处理步骤2的记录，帅选相同店面最大日期记录，然后把这些当前更新分销记录的LastDistributionDate__c更新为starttime的日期。
    //5.  更新4步骤得到的数据相关店面的其他这个月或上个月有分销记录的店面拜访，查询时要排除当前id，把这些其他记录的LastDistributionDate__c更新为空。
    6.  然后处理步骤3记录，先把这些记录的LastDistributionDate__c全部更新为空。
    7.  然后用2里面的记录去匹配3里面的记录，如果有相同店面名称的记录，要把这条记录从3的数据中删除，比如在不同日期分别上传了两条店面A记录，其中一条有分销，另外一条无分销但之前是有分销的，对于这种情况只需把后者的LastDistributionDate__c更新为空。
    8.  根据7步骤得到的数据，把这些数据所在店面的其他有分销记录查询出来，先按店面名称名称排序再按startdate降序排序，然后取相当店面的最大日期记录把其LastDistributionDate__c更新为starttime的日期。

 
hxj 2010-10-21

注意在update语句里面，避免联动触发before update trigger造成不必要的upate甚至死循环
hxj 2010-10-25
*/
trigger LastVisitDistributionDateChangeODI on In_Store_Visit__c (before insert, before update) 
{
 
 if(trigger.new.size()>0)
 {
      //变量定义
      string strOutlet='';//outlet id
      //门店Id
      Set<id> setOLId=new  Set<id>();    
      //分别存储跨天上传数据刚好是跨月情况
      Map<id,In_Store_Visit__c>mapThisM=new  Map<id,In_Store_Visit__c>();
      Map<id,In_Store_Visit__c>mapLastM=new  Map<id,In_Store_Visit__c>();
      //记录更新分销时，把有分销的更新成无分销
      Map<string,In_Store_Visit__c>mapThisMNull=new  Map<string,In_Store_Visit__c>();
      Map<string,In_Store_Visit__c>mapLastMNull=new  Map<string,In_Store_Visit__c>();
      Map<id,In_Store_Visit__c> mapOtherNullThM=new Map<id,In_Store_Visit__c>();
      Map<id,In_Store_Visit__c> mapOtherNullLaM=new Map<id,In_Store_Visit__c>();
      //存储其他店面记录 
      Map<id,In_Store_Visit__c> mapOther=new Map<id,In_Store_Visit__c>();
    

      if(trigger.isInsert)
      {       
          list<In_Store_Visit__c> lstIsvTh=new  list<In_Store_Visit__c>();
          list<In_Store_Visit__c> lstIsvLa=new  list<In_Store_Visit__c>();
          list<In_Store_Visit__c> lstTemp=new  list<In_Store_Visit__c>();
         
          for(integer i=0;i<trigger.new.size();i++)
          {                      
            setOLId.add(trigger.new[i].OutletName_del__c);
            
             //跨天时本月数据
            if(trigger.new[i].Start_Time__c.month()==date.today().month())
            {
                lstIsvTh.add(trigger.new[i]);
            }
            else//上个月数据
            {
                if(trigger.new[i].Start_Time__c.month()==date.today().addMonths(-1).month())
                {
                     lstIsvLa.add(trigger.new[i]);
                }
               
            }

          }
           //把当前店面这个月和上个月拜访或计划内数据不为空的选出来
          mapOther= new Map<Id,In_Store_Visit__c>( (List<In_Store_Visit__c>)[select id,OutletName_del__c,LastVisitDate_schedule__c,LastVisitDate__c,RoutingPlanItem__c,Start_Time__c
            from In_Store_Visit__c where OutletName_del__c in:setOLId and (LastVisitDate_schedule__c!=null or LastVisitDate__c!=null)  and (StartDate__c=this_month or StartDate__c=last_month)  limit 1000] ); 
      
        integer iTemp=0;  
         //本月
        if(lstIsvTh.size()>0)
        {
          //先处理本月LastVisitDate__c
          for(integer i=0;i<lstIsvTh.size();i++)
          {
             strOutlet=lstIsvTh[i].OutletName_del__c; 
             iTemp=i;
             for(integer j=i+1;j<lstIsvTh.size();j++)
             {
                 if(lstIsvTh[j].OutletName_del__c==strOutlet&&lstIsvTh[j].Start_Time__c.date()>lstIsvTh[iTemp].Start_Time__c.date())
                 {
                     iTemp=j;
                 }
             }
             if(!mapThisM.containsKey(lstIsvTh[iTemp].OutletName_del__c))
             {
                mapThisM.put(lstIsvTh[iTemp].OutletName_del__c,lstIsvTh[iTemp]);//只保存日期最大的店面
             } 
             
          }    
          //更新当前LastVisitDate__c,其他LastVisitDate__c
          for(In_Store_Visit__c isv:mapThisM.values())
          {
              isv.LastVisitDate__c=isv.Start_Time__c.date();
              for(In_Store_Visit__c i :mapOther.values())
              {
                 if(i.Start_Time__c.month()==date.today().month()&&i.OutletName_del__c==isv.OutletName_del__c)
                 {
                    i.LastVisitDate__c=null;
                 }
              }
          }
        
          mapThisM.clear();
          iTemp=0;
          
           //再处理本月LastVisitDate_schedule__c
          for(integer i=0;i<lstIsvTh.size();i++)
          {
             if(lstIsvTh[i].RoutingPlanItem__c!=null)
             {
                lstTemp.add(lstIsvTh[i]);              
             }
            
          }
          
         for(integer i=0;i<lstTemp.size();i++)
         {
             strOutlet=lstTemp[i].OutletName_del__c; 
             iTemp=i;
             for(integer j=i+1;j<lstTemp.size();j++)
             {
                   if(lstTemp[j].OutletName_del__c==strOutlet&&lstTemp[j].Start_Time__c.date()>lstTemp[iTemp].Start_Time__c.date())
                   {
                      iTemp=j;
                   }
             }
            if(!mapThisM.containsKey(lstTemp[iTemp].OutletName_del__c))
            {
                mapThisM.put(lstTemp[iTemp].OutletName_del__c,lstTemp[iTemp]);//只保存日期最大的店面
            }  
            
          }
          lstTemp.clear();
          //更新当前LastVisitDate_schedule__c,其他LastVisitDate_schedule__c
          for(In_Store_Visit__c isv:mapThisM.values())
          {
              isv.LastVisitDate_schedule__c=isv.Start_Time__c.date();
               for(In_Store_Visit__c i :mapOther.values())
              {
                 if(i.Start_Time__c.month()==date.today().month()&&i.OutletName_del__c==isv.OutletName_del__c)
                 {
                    i.LastVisitDate_schedule__c=null;
                 }
              }
          }
        } 
       //处理上个月记录
        iTemp=0;
        if(lstIsvLa.size()>0)
        {
              //先处理上个月LastVisitDate__c
            for(integer i=0;i<lstIsvLa.size();i++)
            {
               strOutlet=lstIsvLa[i].OutletName_del__c; 
               iTemp=i;
               for(integer j=i+1;j<lstIsvLa.size();j++)
               {
                  if(lstIsvLa[j].OutletName_del__c==strOutlet&&lstIsvLa[j].Start_Time__c.date()>lstIsvLa[iTemp].Start_Time__c.date())
                  {
                     iTemp=j;
                  }
                }
               if(!mapLastM.containsKey(lstIsvLa[iTemp].OutletName_del__c))
               {
                   mapLastM.put(lstIsvLa[iTemp].OutletName_del__c,lstIsvLa[iTemp]);//只保存日期最大的店面
               }
              
             }
           //更新当前LastVisitDate__c,其他LastVisitDate__c
            for(In_Store_Visit__c isv:mapLastM.values())
            {
               isv.LastVisitDate__c=isv.Start_Time__c.date();
               for(In_Store_Visit__c i :mapOther.values())
               {
                  if(i.Start_Time__c.month()==date.today().addMonths(-1).month()&&i.OutletName_del__c==isv.OutletName_del__c)
                  {
                     i.LastVisitDate__c=null;
                  }
               }
              
            }
            mapLastM.clear();
            iTemp=0;
          
           //再处理上个月LastVisitDate_schedule__c
           for(integer i=0;i<lstIsvLa.size();i++)
          {
             if(lstIsvLa[i].RoutingPlanItem__c!=null)
             {
                lstTemp.add(lstIsvLa[i]);              
             }
            
          }
          
         for(integer i=0;i<lstTemp.size();i++)
         {
             strOutlet=lstTemp[i].OutletName_del__c; 
             iTemp=i;
             for(integer j=i+1;j<lstTemp.size();j++)
             {
                   if(lstTemp[j].OutletName_del__c==strOutlet&&lstTemp[j].Start_Time__c.date()>lstTemp[iTemp].Start_Time__c.date())
                   {
                      iTemp=j;
                   }
             }
            if(!mapLastM.containsKey(lstTemp[iTemp].OutletName_del__c))
            {
               mapLastM.put(lstTemp[iTemp].OutletName_del__c,lstTemp[iTemp]);//只保存日期最大的店面
            } 
            
          }
         
           //更新当前LastVisitDate_schedule__c
           for(In_Store_Visit__c isv:mapLastM.values())
           {
               isv.LastVisitDate_schedule__c=isv.Start_Time__c.date();
               for(In_Store_Visit__c i :mapOther.values())
               {
                  if(i.Start_Time__c.month()==date.today().addMonths(-1).month()&&i.OutletName_del__c==isv.OutletName_del__c)
                  {
                     i.LastVisitDate_schedule__c=null;
                  }
               }
               
            }
       }

     }
     else
     {
        if(trigger.isUpdate)
        {                    
           //临时存放当前更新有分销的本月和上个月数据
           list<In_Store_Visit__c> lThMon=new  list<In_Store_Visit__c>();
           list<In_Store_Visit__c> lLaMon=new  list<In_Store_Visit__c>();      
            
          for(integer i=0;i<trigger.new.size();i++)
          {
              strOutlet=trigger.new[i].OutletName_del__c;
              //InventoryDisplayPriceGreaterThan0__c判断为了避免insert触发器的update语句再次联动触发不必要update trigger，以及避免本身update触发器循环触发不必要的update trigger
              //只更新分销信息时触发
              if(trigger.new[i].InventoryDisplayPriceGreaterThan0__c != trigger.oldmap.get(trigger.new[i].id).InventoryDisplayPriceGreaterThan0__c)
              {  
              
                 if(trigger.new[i].InventoryDisplayPriceGreaterThan0__c>0)
                 {
                   if(trigger.new[i].Start_Time__c.month()==date.today().month())//本月数据
                    {
                       lThMon.add(trigger.new[i]);
                    }
                    else//上个月数据
                    {
                        if(trigger.new[i].Start_Time__c.month()==date.today().addMonths(-1).month())
                        {
                             lLaMon.add(trigger.new[i]);
                        }
                       
                    }
                 } 
              
                    //先存储原来有分销后面改成无分销的记录
                    if(trigger.new[i].InventoryDisplayPriceGreaterThan0__c==0
                    &&trigger.oldmap.get(trigger.new[i].id).InventoryDisplayPriceGreaterThan0__c>0
                    &&trigger.oldmap.get(trigger.new[i].id).LastDistributionDate__c!=null)
                    {
                        if(trigger.new[i].Start_Time__c.month()==date.today().month())//本月数据
                       {
                           //以前的记录一个月只有一次分销
                           mapThisMNull.put(trigger.new[i].OutletName_del__c,trigger.new[i]);
                       }
                       else//上个月数据
                       {
                           //以前的记录一个月只有一次分销
                           mapLastMNull.put(trigger.new[i].OutletName_del__c,trigger.new[i]);
                       }
                    }
                   
                //} 
                 
              }
                   
           }
           //对于有分销的记录，如果有相同门店只更新日期最大的记录
            //本月
           if(lThMon.size()>0)
           {  
              integer iTem=0;
              for(integer i=0;i<lThMon.size();i++)
              {
                 iTem=i;
                 for(integer j=i+1;j<lThMon.size();j++)
                 {
                    if(lThMon[j].OutletName_del__c==lThMon[iTem].OutletName_del__c&&lThMon[j].Start_Time__c.date()>lThMon[iTem].Start_Time__c.date())
                    {
                       iTem=j;
                    }
                 }
                 if(!mapThisM.containsKey(lThMon[iTem].OutletName_del__c))
                 {
                    mapThisM.put(lThMon[iTem].OutletName_del__c,lThMon[iTem]);
                 }             
                 //setOLId.add(lThMon[iTem].OutletName_del__c);                  
               }
            }
        
            
            //上个月
            if(lLaMon.size()>0)
           {  
              integer iTem=0;
              for(integer i=0;i<lLaMon.size();i++)
              {
                 iTem=i;
                 for(integer j=i+1;j<lLaMon.size();j++)
                 {
                    if(lLaMon[j].OutletName_del__c==lLaMon[iTem].OutletName_del__c&&lLaMon[j].Start_Time__c.date()>lLaMon[iTem].Start_Time__c.date())
                    {
                       iTem=j;
                    }
                 }
                 if(!mapLastM.containsKey(lLaMon[iTem].OutletName_del__c))
                 {
                     mapLastM.put(lLaMon[iTem].OutletName_del__c,lLaMon[iTem]); 
                 }            
                 //setOLId.add(lLaMon[iTem].OutletName_del__c);        
                           
               }
            }
        
            //对当前更新的店面的其他的店面的处理
            set<ID> ids = Trigger.newMap.keySet();
            
           //处理把原来有分销后面修改成无分销的相关店面，把以前有分销的最大日期记录赋值为改记录的开始日期
            //本月
            
           //先用当前更新有分销的店面去排除这些把原来有分销改成无分销的记录
           for(In_Store_Visit__c isv:mapThisM.values())
           {
              if(mapThisMNull.containsKey(isv.OutletName_del__c))
              {
                  mapThisMNull.remove(isv.OutletName_del__c);
              }
           }
           //把原来有分销修改成无分销的记录，置空分销日期
            for(In_Store_Visit__c isv:mapThisMNull.values())
           {
               isv.LastDistributionDate__c=null;
           }
           
           if(mapThisMNull.size()>0)
           {
              Map<id,In_Store_Visit__c>mapTemp=new Map<Id,In_Store_Visit__c>( (List<In_Store_Visit__c>)[select id,OutletName_del__c,Start_Time__c,LastDistributionDate__c
                from In_Store_Visit__c where OutletName_del__c in:mapThisMNull.keySet() and InventoryDisplayPriceGreaterThan0__c>0 and LastDistributionDate__c=null
                and id not in :ids and StartDate__c=this_month  order by  StartDate__c desc,OutletName_del__c asc limit 1000] );  
                
                if(mapTemp.size()>0)
                {
                   for(In_Store_Visit__c isv:mapTemp.values())
                   {
                      //取唯一店面日期最大的记录
                      if(!mapOtherNullThM.containsKey(isv.OutletName_del__c))
                      {
                         mapOtherNullThM.put(isv.OutletName_del__c,isv);
                      }
                      
                   }
                   //把这些记录赋值分销日期
                   for(In_Store_Visit__c isv:mapOtherNullThM.values())
                   {
                       isv.LastDistributionDate__c=isv.Start_Time__c.date();
                   }
                }

           }
            //上个月
           //先用当前更新有分销的店面去排除
           for(In_Store_Visit__c isv:mapLastM.values())
           {
              if(!mapLastMNull.containsKey(isv.OutletName_del__c))
              {
                  mapLastMNull.remove(isv.OutletName_del__c);
              }
           }
            //把当前有分销修改成无分销的记录，置空分销日期
           for(In_Store_Visit__c isv:mapLastMNull.values())
           {
               isv.LastDistributionDate__c=null;
           }
           if(mapLastMNull.size()>0)
           {
              Map<id,In_Store_Visit__c>mapTemp=new Map<Id,In_Store_Visit__c>( (List<In_Store_Visit__c>)[select id,OutletName_del__c,Start_Time__c,LastDistributionDate__c
                from In_Store_Visit__c where OutletName_del__c in:mapLastMNull.keySet() and InventoryDisplayPriceGreaterThan0__c>0 and LastDistributionDate__c=null
                and id not in :ids and StartDate__c=last_month  order by  StartDate__c desc,OutletName_del__c asc limit 1000] );  
                
                if(mapTemp.size()>0)
                {
                   for(In_Store_Visit__c isv:mapTemp.values())
                   {
                      //取唯一店面日期最大的记录
                      if(!mapOtherNullLaM.containsKey(isv.OutletName_del__c))
                      {
                         mapOtherNullLaM.put(isv.OutletName_del__c,isv);
                      }
                      
                   }
                   //把这些记录赋值分销日期
                   for(In_Store_Visit__c isv:mapOtherNullLaM.values())
                   {
                       isv.LastDistributionDate__c=isv.Start_Time__c.date();
                   }
                }

           }
              
         }
    }
      
      //最后一起更新其他所有记录
     if(mapOther.size()>0)
     {                              
         update mapOther.values();    
     } 
     
     if(mapOtherNullThM.size()>0)
     {
         update mapOtherNullThM.values();
     } 
     
     if(mapOtherNullLaM.size()>0)
     {
         update  mapOtherNullLaM.values();
     }
      
   }

    
 }